package com.newlink.building.login.mvp.presenter

import android.content.Context
import android.content.Intent
import android.util.Log
import com.newlink.building.login.R
import com.newlink.building.login.mvp.contract.Module_Login_LoginContract
import com.newlink.building.login.mvp.model.Module_Login_LoginModel
import com.newlink.building.common_base.activities.NL_WebViewActivityNL
import com.newlink.building.common_base.base.BasePresenter
import com.newlink.building.common_base.constant.Base_Constant.PRIVACY_POLICY_URL
import com.newlink.building.common_base.constant.Base_Constant.PRIVACY_POLICY_URL_EN
import com.newlink.building.common_base.constant.Base_Constant.USER_LICENSES_URL
import com.newlink.building.common_base.constant.Base_Constant.USER_LICENSES_URL_EN
import com.newlink.building.common_base.ext.ss
import com.newlink.building.common_base.ext.sss
import com.newlink.building.common_base.http.exception.Base_ErrorStatus
import com.newlink.building.common_base.model.bean.KitDeviceData
import com.newlink.building.common_base.model.bean.LoginMsgCodeBean
import com.newlink.building.common_base.model.bean.LoginRequestBean
import com.newlink.building.common_base.model.bean.LoginSipAccountRequestBean
import com.newlink.building.common_base.model.bean.SipRequest
import com.newlink.building.common_base.utils.Base_Base64
import com.newlink.building.common_base.utils.NLog
import com.newlink.building.common_base.utils.LocaleUtils
import com.newlink.building.common_base.utils.logDebug
import com.newlink.building.crypt.library_crypt.digest.Md5Crypt
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationHelper
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationInvoker
import org.json.JSONArray
import org.json.JSONObject
import androidx.core.net.toUri

/**
 * Created by xiaodong on 2022/8/24.
 */
class Module_Login_LoginPresenter : BasePresenter<Module_Login_LoginContract.Model, Module_Login_LoginContract.View>(),
    Module_Login_LoginContract.Presenter {

    override fun createModel(): Module_Login_LoginContract.Model = Module_Login_LoginModel()

    /**
     * 获取token接口
     */
    override fun login(user: String, password: String) {
        // 登录操作前的安全混淆
        Module_Obfuscation_ObfuscationHelper.onMethodEnter("LoginPresenter", "login")
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(user.hashCode())
        Module_Obfuscation_ObfuscationHelper.beforeNetworkRequest(
            "LOGIN",
            mapOf("user" to user, "password" to password)
        )

        val base64Pwd = Base_Base64.encode(password.toByteArray())
        logDebug<Module_Login_LoginPresenter>("LoginPresenter login $user $password -> $base64Pwd")

        mModel?.login(LoginRequestBean(user, base64Pwd))?.sss(view = mView, onSuccess = {
            logDebug<Module_Login_LoginPresenter>("login response ->  ${it.data}")
            val loginResponseData = it.data
            mView?.onGetTokenSuccess(loginResponseData.access_token, loginResponseData.userId)
        }, onError = {
            mView?.onLoginFail(it.msg)
        })
    }

    override fun loginBySipAccount(sip: String, password: String) {
        // SIP账号登录前的混淆
        Module_Obfuscation_ObfuscationHelper.beforeNetworkRequest("SIP_LOGIN", mapOf(sip to password))
        Module_Obfuscation_ObfuscationInvoker.invokeSpecific(5, sip)

        val base64Pwd = Base_Base64.encode(password.toByteArray())
        logDebug<Module_Login_LoginPresenter>("LoginPresenter login $sip $password -> $base64Pwd")

        mModel?.loginWithSipAccount(LoginSipAccountRequestBean(sip, base64Pwd))?.ss(mModel, mView) {
            logDebug<Module_Login_LoginPresenter>("login response ->  ${it?.data}")
            if (it?.data == null) {
                mView?.onLoginFail(it?.msg)
            } else {
                val loginResponseData = it.data
                mView?.onGetTokenSuccess(loginResponseData.access_token, loginResponseData.userId)
            }
        }
    }

    override fun loginWithQR(userName: String, password: String) {
        logDebug<Module_Login_LoginPresenter>("LoginPresenter loginWithQR ---> $userName $password")
        mModel?.loginWithQR(userName, password)?.ss(mModel, mView) {
            logDebug<Module_Login_LoginPresenter>("login response ->  ${it?.data}")
            if (it?.data == null) {
                mView?.onLoginFail(it?.msg)
            } else {
                val loginResponseData = it.data
                mView?.onGetTokenSuccess(loginResponseData.access_token, loginResponseData.userId)
            }
        }
    }

    override fun loginFls(user: String, password: String, userCategory: Int, needEncrypt: Boolean) {
        // FLS登录前的安全混淆
        Module_Obfuscation_ObfuscationHelper.onMethodEnter("LoginPresenter", "loginFls")
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(userCategory.toLong())
        Module_Obfuscation_ObfuscationHelper.beforeDatabaseOperation("FLS_LOGIN", user)

        val password1 = if (needEncrypt) {
            Md5Crypt.md5(password)
        } else {
            password
        }

        mModel?.login(LoginRequestBean(user, password1, userCategory))?.ss(mModel, mView) {
            logDebug<Module_Login_LoginPresenter>("loginFls response ->  ${it?.data}")
            if (it?.code == Base_ErrorStatus.ERROR) {
                mView?.onLoginFail(it.msg)
            } else if (it?.data == null) {
                mView?.onLoginFail(it?.msg)
            } else {
                val loginResponseData = it.data
                mView?.onGetTokenSuccess(loginResponseData.access_token, loginResponseData.userId)
            }
        }
    }

    override fun loginFlsMsgCode(
        area: String,
        mobileNumber: String,
        code: String,
        userCategory: Int,
    ) {
        mModel?.loginWithMsgCode(LoginMsgCodeBean(area, mobileNumber, code, userCategory))
            ?.ss(mModel, mView) {
                logDebug<Module_Login_LoginPresenter>("loginFls response ->  ${it?.data}")
                if (it?.code == Base_ErrorStatus.ERROR) {
                    mView?.onLoginFail(it.msg)
                } else if (it?.data == null) {
                    mView?.onLoginFail(it?.msg)
                } else {
                    val loginResponseData = it.data
                    mView?.onGetTokenSuccess(
                        loginResponseData.access_token,
                        loginResponseData.userId
                    )
                }
            }
    }

    /**
     * 获取用户详情信息
     */
    override fun getUserInformation(token: String, userId: Long) {
        logDebug<Module_Login_LoginPresenter>("[jake] getUserInformation....")
        mModel?.getUserInfo(token, userId)?.ss(mModel, mView) { infoData ->
            logDebug<Module_Login_LoginPresenter>("[jake] getUserInformation response ->  ${infoData?.data}")
            if (infoData?.data == null) {
                mView?.onGetUserInfoFailed()
            } else {
                mView?.onGetUserInfoSuccess(infoData.data)
            }
        }
    }

    override fun getKcpInformation(token: String, userId: Long) {
        mModel?.getKcpInformation(token, userId)?.ss(mModel, mView) { infoData ->
            logDebug<Module_Login_LoginPresenter>("getKcpInformation response ->  ${infoData?.data}")
            if (infoData?.data == null) {
                logDebug<Module_Login_LoginPresenter>("3333333333333333")
                mView?.onKcpFail()
            } else {
                logDebug<Module_Login_LoginPresenter>("34444444444444444 $infoData")
                mView?.onGetKcpInfoSuccess(infoData?.data!!)
            }
        }
    }

    override fun getAppConfig(token: String) {
        logDebug<Module_Login_LoginPresenter>("[jake] LoginPresenter getMqttInformation start ->  ")
        mModel?.getAppConfig(token)?.ss(mModel, mView) {
            if (it?.data != null) {
                logDebug<Module_Login_LoginPresenter>("[jake] getMqttdata success ${it.data}  ")
                mView?.onGetAppConfigSuccess(it.data)
            } else {
                mView?.onAppConfigFail()
            }
        }
    }

    override fun startBrowser(context: Context, url: String) {
        val intent = Intent()
        intent.action = "android.intent.action.VIEW"
        intent.data = url.toUri()
        intent.setClassName(
            "com.android.browser",
            "com.android.browser.BrowserActivity"
        )
        context.startActivity(intent)
    }

    override fun showUserLicense(context: Context, type: Int) {
        var url = ""
        var title = ""
        when (type) {
            0 -> {
                url =
                    if (LocaleUtils.isSystemLocaleZh()) USER_LICENSES_URL else USER_LICENSES_URL_EN
                title = context.resources.getString(R.string.user_register_license_user)
            }

            1 -> {
                url =
                    if (LocaleUtils.isSystemLocaleZh()) PRIVACY_POLICY_URL else PRIVACY_POLICY_URL_EN
                title = context.resources.getString(R.string.user_register_license_content)
            }
        }
        if (url.isNotEmpty() && title.isNotEmpty()) {
            NL_WebViewActivityNL.startSelf(context, url, title)
        }
    }

    override fun getUserNameFromQrcode(qrcode: String): List<String> {
        var qrInfo = mutableListOf<String>()
        qrInfo.clear()
        try {
            val decodeVal = Base_Base64.decode(qrcode)
            NLog.e("jake...${String(decodeVal)}")
            decodeVal.let {
                val jsonObject = JSONObject(String(decodeVal))
                qrInfo.add(jsonObject.getString("userId"))
                qrInfo.add(jsonObject.getString("pwd"))
                qrInfo.add(jsonObject.getString("regionId"))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        logDebug<Module_Login_LoginPresenter>("connectKcp response ->  二维码解析结果...${qrInfo}")
        return qrInfo
    }

    override fun getKitDeviceDataFromQrcode(qrcode: String): ArrayList<KitDeviceData> {
        val deviceDatas = arrayListOf<KitDeviceData>()
        try {
            val jsonArray = JSONArray(qrcode)
            for (i in 0 until jsonArray.length()) {
                val jsonObj = jsonArray.getJSONObject(i)
                val name = jsonObj.optString("name")
                val mac = jsonObj.optString("mac")
                val type = jsonObj.optInt("type")
                val doors = jsonObj.optInt("doors")
                deviceDatas.add(KitDeviceData(name = name, mac = mac, type = type, doors = doors))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        logDebug<Module_Login_LoginPresenter>("getKitDeviceDataFromQrcode response ->  二维码解析结果...${deviceDatas}")
        return deviceDatas
    }

    override fun requestSipRegister(data: SipRequest) {
        logDebug<Module_Login_LoginPresenter>("requestSipRegister data ->  data")
        mModel?.requestSipRegister(data)
    }

    override fun getVerifyCode(areaCode: String, phoneNumber: String, userCategory: Int) {
        mModel?.getVerifyCode(areaCode, phoneNumber, userCategory)?.ss(mModel, mView) {
            logDebug<Module_Login_LoginPresenter>("getVerifyCode response ->  ${it?.data}")
            if (it?.code == Base_ErrorStatus.SUCCESS) {
                mView?.onGetVerifyCodeSuccess()
            } else {
                mView?.onGetVerifyCodeFailed(it?.msg)
            }

        }
    }

    override fun getFcmsInfoList(region: String, language: String) {
        Log.d("LoginPresenter", "getFcmsInfoList: region=$region, language=$language")
        // 首先使用本地默认数据
        mView?.onFcmsLoadLocalFirst()

        // 然后异步尝试网络请求更新
        mModel?.getFcmsInfoList(region, language)?.ss(mModel, mView) {
            Log.d("LoginPresenter", "getFcmsInfoList response: data=${it?.data?.size ?: 0} items")
            if (it?.data != null && it.data.isNotEmpty()) {
                Log.d("LoginPresenter", "网络请求成功，更新服务器列表")
                mView?.onFcmsSuccess(it.data)
            } else {
                Log.d("LoginPresenter", "网络请求失败或数据为空，继续使用本地数据")
            }
        }
    }

    override fun getAgreement() {
        mModel?.getAgreement()?.ss(mModel, mView) {
            mView?.onGetAgreementSuccess(it?.data)
        }
    }
}